/******************************************************************************
 * @file rd0ff_bsp_adda_driver.c
 * @brief ADDA驱动实现文件
 *
 * 详细描述：
 * - 功能1：实现ADDA驱动的初始化和去初始化函数
 * - 功能2：提供ADC和DAC的启动、停止操作接口
 * - 功能3：实现驱动实例的创建和管理
 * - 功能4：包含参数验证和错误处理机制
 *
 * @author 陈泳行 | R&D Dept. | Jin Dou Aerospace 金斗航天
 * @date 2025-6-29
 * @version 1.0.0
 *
 * @version_history
 * - 1.0.0 (2025-6-29): 初始版本，实现基本功能
 *
 * @note 本文件依赖rd0ff_bsp_adda_config.h配置文件
 * @warning 驱动初始化前必须确保HAL库已正确初始化
 ******************************************************************************/
#include "rd0ff_bsp_adda_driver.h"

/**
 * @brief DAC初始化函数
 *
 * 初始化DAC外设，配置硬件参数并设置初始化状态。
 * 包含参数验证和重复初始化检查。
 *
 * @param dac DAC设备结构体指针
 * @return adda_ret_t 操作结果状态码
 * @retval ADD_RET_OK 初始化成功
 * @retval ADD_RET_INVALID_PARAM 参数无效（dac为NULL）
 * @retval ADD_RET_ERROR 重复初始化
 */
adda_ret_t __dac_init(bsp_dac_t * dac)
{
    // 1.检查参数是否正确
    if(NULL == dac)
    {
         return ADD_RET_INVALID_PARAM; // 参数检查
    }

    // 2.检查是否重复初始化
    if(DA_INIT == dac->adda_init)
    {
        return ADD_RET_ERROR; // 重复初始化
    }

    // 3.调用MX DAC初始化函数
    dac->pfinit(NULL);
    dac->adda_init = DA_INIT;

    return ADD_RET_OK;
}

/**
 * @brief DAC去初始化函数
 *
 * 停止DAC外设工作，释放资源并重置初始化状态。
 * 包含参数验证和未初始化检查。
 *
 * @param dac DAC设备结构体指针
 * @return adda_ret_t 操作结果状态码
 * @retval ADD_RET_OK 去初始化成功
 * @retval ADD_RET_INVALID_PARAM 参数无效（dac为NULL）
 * @retval ADD_RET_ERROR 设备未初始化
 */
adda_ret_t __dac_deinit(bsp_dac_t * dac)
{
    // 1.检查参数是否正确
    if(NULL == dac)
    {
         return ADD_RET_INVALID_PARAM; // 参数检查
    }
    // 2.检查是否初始化
    if(DA_NOT_INIT == dac->adda_init)
    {
        return ADD_RET_ERROR; // 未初始化
    }
    // 3.调用MX DAC去初始化函数
    dac->pfdeinit(dac->hdac);
    dac->adda_init = DA_NOT_INIT;
    return ADD_RET_OK;
}

/**
 * @brief ADC初始化函数
 *
 * 初始化ADC外设，配置硬件参数并设置初始化状态。
 * 包含参数验证和重复初始化检查。
 *
 * @param adc ADC设备结构体指针
 * @return adda_ret_t 操作结果状态码
 * @retval ADD_RET_OK 初始化成功
 * @retval ADD_RET_INVALID_PARAM 参数无效（adc为NULL）
 * @retval ADD_RET_ERROR 重复初始化
 */
adda_ret_t __adc_init(bsp_adc_t * adc)
{
    // 1.检查参数是否正确
    if(NULL == adc)
    {
         return ADD_RET_INVALID_PARAM; // 参数检查
    }

    // 2.检查是否重复初始化
    if(AD_INIT == adc->adda_init)
    {
        return ADD_RET_ERROR; // 重复初始化
    }

    // 3.调用MX ADC初始化函数
    adc->pfinit(NULL);
    adc->adda_init = AD_INIT;

    return ADD_RET_OK;
}

/**
 * @brief ADC去初始化函数
 *
 * 停止ADC外设工作，释放资源并重置初始化状态。
 * 包含参数验证和未初始化检查。
 *
 * @param adc ADC设备结构体指针
 * @return adda_ret_t 操作结果状态码
 * @retval ADD_RET_OK 去初始化成功
 * @retval ADD_RET_INVALID_PARAM 参数无效（adc为NULL）
 * @retval ADD_RET_ERROR 设备未初始化
 */
adda_ret_t __adc_deinit(bsp_adc_t *adc)
{
    // 1.检查参数是否正确
    if(NULL == adc)
    {
        return ADD_RET_INVALID_PARAM; // 参数检查
    }
    // 2.检查是否初始化
    if(AD_NOT_INIT == adc->adda_init)
    {
        return ADD_RET_ERROR; // 未初始化
    }
    // 3.调用MX ADC去初始化函数
    adc->pfdeinit(adc->hadc);
    adc->adda_init = AD_NOT_INIT;
    return ADD_RET_OK;
}

/**
 * @brief ADDA驱动实例初始化函数
 *
 * 初始化ADDA驱动实例，绑定硬件接口和系统函数，完成ADC和DAC的硬件初始化。
 * 该函数是ADDA驱动的入口点，必须在使用ADDA功能前调用。
 *
 * @param adda_instance ADDA驱动实例指针
 * @param adda ADDA设备结构体指针
 * @param time_base 时基函数结构体指针
 * @param os_delay OS延迟函数结构体指针（仅OS_DEFINE定义时有效）
 * @param os_critical OS临界区函数结构体指针（仅OS_DEFINE定义时有效）
 *
 * @return adda_ret_t 操作结果状态码
 * @retval ADD_RET_OK 初始化成功
 * @retval ADD_RET_INVALID_PARAM 参数无效
 * @retval ADD_RET_ERROR ADC或DAC初始化失败
 */
adda_ret_t adda_driver_inst(
            bsp_adda_driver_t   *adda_instance,
			bsp_dac_t 		    *dac,
			bsp_adc_t 		    *adc,
            time_base_t         *time_base,
#if OS_DEFINE
            os_delay_t          *os_delay,
            os_critical_t       *os_critical
#endif
                                                )
{
    adda_ret_t ret = ADD_RET_OK;

    // 1.参数检查 # 验证输入指针有效性
    if (NULL == adda_instance || 
        NULL == dac           || 
        NULL == adc           || 
        NULL == time_base
#if OS_DEFINE
        || NULL == os_delay   
#endif
                                 ) 
    {
        return ADD_RET_INVALID_PARAM;
    }

    // 2.结构体成员初始化 # 绑定硬件接口和时基函数
    adda_instance->dac              = dac;
    adda_instance->adc              = adc;
    adda_instance->pftimebase_port  = time_base;
#if OS_DEFINE
    adda_instance->os_delay_port    = os_delay;
    adda_instance->os_critical_port = os_critical;
#endif
    // 初始化标志位
    adda_instance->status              = ADDA_DRIVER_NOT_INIT;
    adda_instance->dac->adda_init = DA_NOT_INIT;
    adda_instance->adc->adda_init = AD_NOT_INIT;
    
    // 3.硬件初始化 # 调用DAC和ADC初始化函数
    if(NULL != dac->pfinit)
    {
        ret = __dac_init(dac);
        if(ADD_RET_OK != ret)
        {
            return ADD_RET_ERROR;
        }
    }
    if(NULL != adc->pfinit)
    {
        ret = __adc_init(adc);
        if(ADD_RET_OK != ret)
        {
            return ADD_RET_ERROR;
        }
    }
    // 防止传入的空初始化函数
    if(DA_NOT_INIT == adda_instance->dac->adda_init ||
       AD_NOT_INIT == adda_instance->adc->adda_init   )
    {
        return ADD_RET_ERROR;
    }

    adda_instance->status = ADDA_DRIVER_INIT;
    return ADD_RET_OK; // 返回初始化成功
}

